/*
 * Università degli Studi di Trento
 * Facoltà di Scienze MM.FF.NN.
 * Corso di Laurea Triennale in Informatica
 * A.A. 2011/2012
 * Progetto per il corso di Sistemi Operativi 1
 * Progetto 3: 
 * Autori:
 * Bertoldi Lorenzo 155863
 * Cattin Cosso Manuel 146607
 * Parrello Nicola 145610
 */

#include "threadPadre.h"
#include "listaThread.h"
#include "definizioni.h"


/*
 * Da questo file viene gestita l'esecuzione dell'intero programma
 */

int main(int argc, char** argv) {    
    int c;
    opterr = 0;
    //Controlla se e' stato chiesto di visualizzare l'help
    while ((c = getopt (argc, argv, "h")) != -1){
        switch (c){
           case 'h':
               printf("cmd help:\nPermette di eseguire numerosi comandi in maniera autonoma.\n");
               printf("I comandi vengono avviati in maniera casuale e ");
               printf("il loro l'output viene registrato all'interno della directory: '");
               printf(LOGDIRECTORY "' in un apposito file creato con la sintassi: \n");
               printf("'cmd.nomeComando.ora.minuti.secondi.giorno.mese.anno.out'\n");
               printf("\nNon e' permsesso l'uso del comando exit, in questo caso il processo non viene avviato.\n");
             return 0;
           case '?':
               fprintf (stderr,
                        "Unknown option character `\\x%x'.\n",
                        optopt);
             return 1;
           default:
             abort ();
           }
    }
    
    //Se non vi sono comandi da eseguire si esce dal programma
    if(argc<2){
        printf("Indicare almeno un comando da eseguire\n");
        return 1;
    }
    
    //Crea il threadPrincipale
    pThreadPadre tp= ThreadPadre_create();
    int index = optind;
    //Ottieni i comandi da avviare
    while( index < argc){
        fprintf(tp->file,"Il comando %d vale %s\n",index,argv[index]);
        if(strcmp("exit",argv[index])==0){
            fprintf(tp->file,"Il parametro numero %d non e' stato avviato poiche' coincide con il comando exit\n",index);
        }else{
            ThreadPadre_newFiglio(tp, argv[index]);
        }
        index++;
    }
    int avviato=-1;
    //Se vi sono comandi da avviare avviane uno
    //Finche' ci sono comandi in esecuzione o in attesa di essere eseguiti
    while( tp->listaFigli->dim > 0 ){
        if((tp->listaFigli->dim) > tp->listaFigli->attivi ){
            avviato=ThreadPadre_avviaFiglioCasualmente(tp);
            while(avviato==-1){
                avviato=ThreadPadre_avviaFiglioCasualmente(tp);
            }
        }
        //Leggi e scrivi l'output
        ThreadPadre_ascoltaEScrivi(tp);
        fprintf(tp->file,"Ricompatto la lista dei processi\n");
        //Rimuovi i processi che non sono piu' attivi
        int rim=ListaThread_ricompattaLista(tp->listaFigli);
        fprintf(tp->file,"Ho rimosso %d thread\n", rim);
        //Se vi sono programmi in attesa di essere avviati avviane uno
    }
    //Libera la memoria
    ThreadPadre_destroy(tp);
    
    return (EXIT_SUCCESS);
}

